Writing a Query Definition Function
definition function specified by the queryProc field in the QueryRecord. The purpose of the query definition function is to modify the query and the
QueryRecord before the query is sent to the data server. The query definition function can use dialog boxes to request information from the user.
Because a query document is most useful if it can be used by many different
applications, no query definition function should depend on the presence of a
particular application.
If you want to include a query definition function, you must make it the first
piece of code in a resource of type 'qdef' in the query document.
Here is a function declaration for a query definition function.
pascal OSErr MyQDef (long sessID, QueryHandle query); If the application has already initiated a session with the data server, the
DBStartQuery function passes the session ID for that session in the sessID parameter to the query definition function. If the query definition function
initiated a session. In this case, the query definition function can return a 0 in
the sessID parameter, or it can call the DBInit function to initiate a session and then return the session ID in this parameter.
If the query definition function returns a 0 in the sessID parameter, the
DBSend function to send a query to the data server. If the query definition function returns a session ID in this parameter, the DBStartQuery function calls the DBSend function immediately. The query parameter to the query definition function specifies a handle to the
QueryRecord. The query definition function can modify any of the fields in the QueryRecord, including the currQuery field that specifies which query is to be sent to the data server. In addition, the query definition function can
modify an existing query or create a new query, adding the handle to the new
query to the query list. Note that, because a query in memory consists only of a
2-byte length value followed by a character string, the query definition
function has to know the exact contents and structure of a query in order to
modify it.
The query definition function must return the noErr result code as the
function result if the function executed successfully. If it returns any other
query definition function can return any result code, including noErr,
userCanceledErr, or rcDBError.
When the DBStartQuery function calls the query definition function, the current resource file is the file that contains the 'qrsc' resource from which
resource file must be unchanged.
The query definition function can allocate memory and use the dataHandle field
in theQueryRecord to store a handle to it. The query definition function must free any memory it allocates before terminating.
The Listing below shows a query definition function that uses a dialog box to
prompt the user for a user name and password and then modifies the
// A query definition function
// Assuming inclusion of
#include <DatabaseAccess.h>
#include < string.h>
# define myNameItem Command
# define myPassWordItem CodeExampleStart
pascal OSErr MyQDef (long * sessID, QueryHandle query); *theEvent, short *itemHit);
pascal OSErr MyQDef (long * sessID, QueryHandle query) {
short myNumRes;
ResListPtr myResLPtr;
short myIndex;
short myDlogID;
short itemType;
short itemHit;
// If sessID = 0, no session has been
// initiated. Your qdef may optionally initiate a
// care of this. In this example, the qdef doesn't
// check the sessID parameter.
myNumRes = (* query)->numRes;
myResList = (* query)->resList;
myResLPtr = *myResList;
myIndex = 0;
// Look for a 'DLOG' resource
while ( (myIndex < myNumRes) || (myResLPtr[myIndex].theType !=
'DLOG') )
myIndex = myIndex + 1;
// Was a 'DLOG' resource found, or did the index run out?
if (myIndex < myNumRes)
myDlogID = myResLPtr[myIndex].id;
// We found the 'DLOG' resource.
else {
// The 'DLOG' wasn't found; exit with no error. This
// is probably okay; it just means that the query
// and the query record don't get modified.
return;
}
// Found the 'DLOG' and its ID; now put up the dialog box.
// Now you can change the query record or the query itself.
// What you change is entirely up to you. In this example,
// the qdef changes only the user and password fields
GetDItem(myDialog, myNameItem, &itemType, &itemHName, &itemBox); GetDItem(myDialog, myPassWordItem, &itemType, &itemHPasswd, &itemBox);
// Make available to the filter routine the strings
// we want the user to edit.
((WindowPeek) myDialog)->refCon = (long) mySTR;
// myNamePasswdFltrFunc is a routine that allows the user to edit
// the name and password fields in the dialog box
if (itemHit == ok) {
// The user clicked the OK button. Update the user and password
strcpy ((char *) (* query)->user, PtoCstr (mySTR[1]));
CtoPstr ((char *) (* query)->user);
strcpy ((char *) (* query)->password, PtoCstr (mySTR[2]));
CtoPstr ((char *) (* query)->password);
}
else
}